/**
 * 各个数据格式转化的方法集合
 */
import moment from 'moment';
import _ from 'lodash';
import dayjs from 'dayjs';
import duration from 'dayjs/plugin/duration'
dayjs.extend(duration)
/**
 * 转化字节数到对应的量级(TB,GB,MB,KB)
 * @param {number} y 默认是B
 */
export const formatKMBT = (y, reserve = 2) => {
    const yy = Math.abs(y);
    if (yy >= Math.pow(1024, 4)) {
        return y < 0
            ? -1 * +(yy / Math.pow(1024, 4)).toFixed(reserve) + 'T'
            : (yy / Math.pow(1024, 4)).toFixed(reserve) + 'T';
    } else if (yy >= Math.pow(1024, 3)) {
        return y < 0
            ? -1 * +(yy / Math.pow(1024, 3)).toFixed(reserve) + 'G'
            : (yy / Math.pow(1024, 3)).toFixed(reserve) + 'G';
    } else if (yy >= Math.pow(1024, 2)) {
        return y < 0
            ? -1 * +(yy / Math.pow(1024, 2)).toFixed(reserve) + 'M'
            : (yy / Math.pow(1024, 2)).toFixed(reserve) + 'M';
    } else if (yy >= 1024) {
        return y < 0 ? -1 * +(yy / 1024).toFixed(reserve) + 'K' : (yy / 1024).toFixed(reserve) + 'K';
    } else if (yy < 1024 && yy >= 1) {
        return y < 0 ? -1 * +yy.toFixed(reserve) + 'B' : yy.toFixed(reserve) + 'B';
    } else if (yy < 1 && yy > 0) {
        return y < 0 ? -1 * +yy.toFixed(reserve) + 'B' : yy.toFixed(reserve) + 'B';
    } else if (yy === 0) {
        return 0;
    } else {
        return yy;
    }
};

/**
 * 转化字节数到对应的量级(TB,GB,MB)
 * @param {number} y 默认是MB
 */
export const formatMGT = (y) => {
    const yy = Math.abs(y);
    if (yy >= 1024 * 1024) {
        return y < 0
            ? -1 * +(yy / (1024 * 1024)).toFixed(2) + 'T'
            : (yy / (1024 * 1024)).toFixed(2) + 'T';
    } else if (yy >= 1024) {
        return y < 0 ? -1 * +(yy / 1024).toFixed(2) + 'G' : (yy / 1024).toFixed(2) + 'G';
    } else if (yy < 1024 && yy >= 1) {
        return y < 0 ? -1 * +yy.toFixed(2) + 'M' : yy.toFixed(2) + 'M';
    } else if (yy < 1 && yy > 0) {
        return y < 0 ? -1 * yy + 'M' : yy + 'M';
    } else if (yy === 0) {
        return 0;
    } else {
        return yy + 'M';
    }
};

// 转化为标准时间格式
export const formatUTCTime = (time) => {
    // 如果是hyphen，返回
    if (!parseFloat(time)) return time;
    return time && dayjs(time).format('YYYY-MM-DD HH:mm:ss');
};

/**
 * [时间单位转换-毫秒]
 * 默认 ms
 * @param   {[type]}  time [time value]
 * @return  {[type]}       [time value with unit]
 */
export const formatTime = (time, reserve = 2) => {
    let flag = false;
    if (time === 'NaN' || time === undefined) {
        return 0;
    } else {
        flag = time < 0;
        time = Math.abs(time);
        if (time > 3600000) {
            time = (time / 3600000).toFixed(reserve) + 'h';
        } else if (time >= 60000) {
            time = (time / 60000).toFixed(reserve) + 'min';
        } else if (time >= 1000) {
            time = (time / 1000).toFixed(reserve) + 's';
        } else if (time >= 10) {
            time = time.toFixed(reserve) + 'ms';
        } else if (time > 0) {
            time = time.toFixed(reserve) + 'ms';
        } else {
            time = time.toFixed(reserve);
        }
        return flag ? '-' + time : time;
    }
};

/**
 * [时间单位转换-微秒]
 * 默认 μs
 * @param   {[type]}  time [time value]
 * @return  {[type]}       [time value with unit]
 */
export const formatTimeUs = (time, reserve = 2) => {
    let flag = false;
    if (time === 'NaN' || time === undefined) {
        return 0;
    } else {
        flag = time < 0;
        time = Math.abs(time);
        if (time > 3600000000) {
            time = (time / 3600000000).toFixed(reserve) + 'h';
        } else if (time >= 60000000) {
            time = (time / 60000000).toFixed(reserve) + 'min';
        } else if (time >= 1000000) {
            time = (time / 1000000).toFixed(reserve) + 's';
        } else if (time >= 1000) {
            time = (time / 1000).toFixed(reserve) + 'ms';
        } else {
            time = time.toFixed(reserve) + 'μs';
        }
        return flag ? '-' + time : time;
    }
};

/**
 * [时间单位转换-纳秒]
 * 默认 ns
 * @param   {[type]}  time [time value]
 * @return  {[type]}       [time value with unit]
 */
export const formatTimeNs = (time, reserve = 2) => {
    let flag = false;
    if (time === 'NaN' || time === undefined) {
        return 0;
    } else {
        flag = time < 0;
        time = Math.abs(time);
        if (time > 3600000000000) {
            time = (time / 3600000000000).toFixed(reserve) + 'h';
        } else if (time >= 60000000000) {
            time = (time / 60000000000).toFixed(reserve) + 'min';
        } else if (time >= 1000000000) {
            time = (time / 1000000000).toFixed(reserve) + 's';
        } else if (time >= 1000000) {
            time = (time / 1000000).toFixed(reserve) + 'ms';
        } else if (time > 1000) {
            time = (time / 1000).toFixed(reserve) + 'μs';
        } else {
            time = time.toFixed(reserve) + 'ns';
        }
        return flag ? '-' + time : time;
    }
};

export const formatCount = (y, reserve = 2) => {
    const WAN = 10000;
    const YI = 100000000;
    const ZHAO = 1000000000000;
    const yy = Math.abs(y);
    if (yy < WAN) {
        return yy;
    }
    if (yy < YI) {
        return `${(yy / WAN).toFixed(reserve)}${decodeURIComponent('%E4%B8%87')}`; // 万
    }
    if (yy < ZHAO) {
        return `${(yy / YI).toFixed(reserve)}${decodeURIComponent('%E4%BA%BF')}`; // 亿
    }
    return `${(yy / ZHAO).toFixed(reserve)}${decodeURIComponent('%E5%85%86')}`; // 兆
};

//小数转化百分比
export const formatPercent = (number, reserve = 2) => {
    if (number !== 0 && !number) {
        return '-';
    }
    if (number === 0) {
        return 0;
    } else {
        if (number >= 0.01) {
            return `${parseFloat(number + '').toFixed(reserve)}%`;
        } else {
            return '<0.01%';
        }
    }
};

export const formatDodRingData = (percent) => {
    if (_.isNumber(percent)) {
        const t_percent = Math.abs(percent);
        if (t_percent > 0 && t_percent < 0.1) {
            return '<0.1%';
        }
        return `${+t_percent.toFixed(1)}%`;
    }
    return '--';
}

// export type IUnit = 'byteMin' | 'byteMins' | 'byte' | 'KB' | 'KB/S' | 'ms' | 'us' | 'ns' | 'count' | '%' | '100%' | '核' | '2' | 'runms' | '个' | 'dr' | '';
export const formatUnit = (data, unit, reserve = 2) => {
    if (data === -1 || data === 'NaN') return 'N/A';
    if (data === undefined || data === null) return '--';
    if (data === '0') return 0;
    switch (unit) {
        case 'byteMin': //后台返回B
            return formatKMBT(data, reserve);
        case 'byteMins': //后台返回B
            return formatKMBT(data) ? formatKMBT(data).toString() + '/s' : 0;
        case 'byte': //后台返回单位MB
            return formatMGT(data);
        case 'KB': //后台返回单位KB
            return formatKMBT(data * 1024);
        case 'KB/S':
            return formatKMBT(data * 1024).toString() + '/S';
        case 'runms':
            return formatRunningTime(data);
        case 'ms': //后台返回ms
            return formatTime(data, reserve);
        case 'us': //后台返回us
            return formatTimeUs(data, reserve);
        case 'ns': //后台返回ns
            return formatTimeNs(data, reserve);
        case 'count': //后台返回数量
            return formatCount(data, reserve);
        case '%': //百分数加单位
            return formatPercent(data, reserve);
        case '100%': //小数转换百分数
            return formatPercent(data * 100, reserve);
        case '核': {
            if (data === 0) return 0;
            const v = parseFloat(data);
            if (v > 0 && v < 0.01) {
                if (v * 1000 < 0.01) return '<0.01微核';
                return (v * 1000).toFixed(2) + '微核';
            }
            return `${v.toFixed(2)}核`;
        }
        case '2':
            if (data === 0) return 0;
            else return `${parseFloat(data).toFixed(2)}`;
        case '个':
            return `${data}个`;
        case 'dr':
            return formatDodRingData(data);
        default:
            return `${data}`;
    }
};

// 将运行时间转化为对应的时间格式，例如：5分钟，5小时，5天，5月等 time单位毫秒
export const formatRunningTime = (time) => {
    if (time <= 0) {
        return 0;
    }
    const t = time / 1000;
    if (t < 60) {
        return Math.floor(t) + '秒';
    } else if ((t / 60) < 60) {
        return Math.floor(t / 60) + '分钟';
    } else if ((t / 3600) <= 24 && (t / 60) > 60) {
        return Math.floor((t / 3600)) + '小时';
    } else if ((t / 3600) > 24 && (t / 3600 / 24) <= 30) {
        return Math.floor((t / 3600 / 24)) + '天';
    } else if ((t / 3600 / 24) > 30 && (t / 3600 / 24) < 365) {
        const duration = dayjs.duration(t, 's');
        const month = duration.get('months');
        const date = duration.get('day');
        return `${month ? month + '月' : ''}${date ? date + '天' : ''}`;
    } else if ((t / 3600 / 24) >= 365) {
        const duration = dayjs.duration(t, 's');
        const month = duration.get('months');
        return Math.floor((t / 3600 / 24 / 365)) + '年' + `${month ? month + '月' : ''}`;
    }
};

/**
 * 自定义折线图tooltip
 * @param params 折线图信息
 * @param unit1 y轴单位
 * @param total 总数-用于计算第二单位值
 * @param unit2 若提供第二个单位，则tooltip展示 xx{unit2} (xx{unit1})，否则展示xx{unit1}
 * @param withoutUnit2Field 多series中，这个字段不展示unit2，只展示xx{unit1}
 * @returns
 */
export const formatChartTooltip = (params, unit1, total, unit2, withoutUnit2Field) => {
  let count = 0;
  let result = `<div style="min-width:200px"><div>${params[0].axisValue}</div>`;
  // 悬浮框tooltip展示按大小从上到下排序
  params.sort((a, b) => b.value - a.value);
  _.forEach(params, (item,index) => {
      if (typeof item.value !== 'undefined' && typeof item.value !== 'object' && item.value !== '-') {
          const field1 = formatUnit(item.value, unit1);
          let field2;
          // 提供unit2并且当前系列名字不是withoutUnit2Field，则计算field2并展示
          if (unit2 && item.seriesName !== withoutUnit2Field && total) {
              if (unit2 === '%') {    // unit2为%，field2=item.value/total
                  field2 = formatUnit(item.value / total, '100%');
              } else {
                  const dataY = unit1 === '%' ? item.value / 100 : item.value;
                  field2 = formatUnit(dataY * total, unit2);
              }
          }
          result += `<div>
              <span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color: ${item.color};"></span>
              <span class="seriesName" data-index="${index}" data-value="${item.seriesName}" style="max-width:300px;word-break:break-all; word-wrap:break-word; white-space:pre-line;">${item.seriesName} &nbsp;&nbsp; </span>
              <span style="float:right">${field2 ? `${field2} (${field1})` : `${field1}`}</span>
          </div>`;
          count++;
      }
  });
  if (count === 0) {
      return null;
  } else {
      result += '</div>';
      return result;
  }
}

/**
 * 自定义折线图tooltip，直接取后台返回中的数据，不根据总量计算。
 * @param params 折线图信息
 * @param unit1 y轴单位
 * @param data 接口数据
 * @param series 当前系列的key
 * @param listName 当前系列的数据key
 * @param valueKey 要取的value
 * @param unit2 若提供第二个单位，则tooltip展示 xx{unit2} (xx{unit1})，否则展示xx{unit1}
 * @returns
 */
export const formatChartTooltipByData = (params, unit1, data, series, listName, valueKey, unit2) => {
  let count = 0;
  let result = `<div style="min-width:200px"><div>${params[0].axisValue}</div>`;
  // 悬浮框tooltip展示按大小从上到下排序
  params.sort((a, b) => b.value - a.value);
  _.forEach(params, item => {
      if (typeof item.value !== 'undefined' && typeof item.value !== 'object' && item.value !== '-') {
          const field1 = formatUnit(item.value, unit1);
          let field2;
          // 提供unit2，则计算field2并展示
          if (data && series && listName && valueKey) {
              const list = _.find(data, { [series]: item.seriesName })[listName];
              field2 = formatUnit(list[item.dataIndex][valueKey], unit2 || '');
          }
          result += `<div>
              <span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color: ${item.color};"></span>
              <span class="seriesName" data-value="${item.seriesName}" style="max-width:300px;word-break:break-all; word-wrap:break-word; white-space:pre-line;">${item.seriesName} &nbsp;&nbsp; </span>
              <span style="float:right">${field2 ? `${field1} (${field2})` : `${field1}`}</span>
          </div>`;
          count++;
      }
  });
  if (count === 0) {
      return null;
  } else {
      result += '</div>';
      return result;
  }
}
